package com.demo.demo.jinhua;

/**
 * Copyright
 *
 * @Author WuHuang
 * @Date 2022/7/8
 */

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;

public class FriedGoldenFlower {
    public static final List<String> POKE = new ArrayList<>(52);
    public static final String[] NUMBERS = {"2", "3", "4", "5", "6", "7", "8", "9", "10", "J", "Q", "K", "A"};
    public static final String[] COLORS = {"♦", "♣", "♥", "♠"};

    public static void main(String[] args) {
        System.out.println("==========欢乐炸金花==========");
        initPoke();
        Player[] players = initPlayer();
        licensing(players);
        comparePlayerPoke(players);
    }

    // 初始化玩家
    private static Player[] initPlayer() {
        Player ly = new Player();
        ly.setName("老有");
        Player lq = new Player();
        lq.setName("老强");
        Player lj = new Player();
        lj.setName("老江");
        Player ll = new Player();
        ll.setName("老亮");
        Player wlb = new Player();
        wlb.setName("王老板");
        System.out.println("赌博的玩家有:" + "老有,老强,老江,老亮,王老板");
        return new Player[]{ly, lq, lj, ll, wlb};
    }

    // 初始化牌
    public static void initPoke() {
        System.out.println("==========开始初始化牌==========");
        for (String color : COLORS) {
            for (String number : NUMBERS) {
                POKE.add(color + number);
            }
        }
        System.out.println("初始化后的牌:"+POKE);
        System.out.println("==========开始洗牌==========");
        Collections.shuffle(POKE);
        System.out.println("洗完后的牌:"+POKE);
    }

    // 得到单个牌的大小:即每张牌在数组NUMBERS的下标值
    public static int getPokeNumberSize(String poke) {
        checkPoke(poke);
        String number;
        if (poke.length() == 3) {
            number = poke.substring(1, 3);
        } else {
            number = poke.substring(1, 2);
        }
        for (int i = 0; i < NUMBERS.length; i++) {
            if (number.equals(NUMBERS[i])) {
                return i;
            }
        }
        return -1;
    }

    // 检验poke是否合法
    private static void checkPoke(String poke) {
        if (poke == null) {
            throw new NullPointerException("poke为空");
        }
        if (poke.length() < 2 || poke.length() > 3) {
            throw new IllegalArgumentException("poke长度不合法");
        }
        String color = poke.substring(0, 1);
        // 判断花色是否正常
        for (String s : COLORS) {
            if (color.equals(s)) {
                return;
            }
        }
        throw new IllegalArgumentException("poke花色不合法");
    }

    // 得到单个牌花色的大小:即每张牌的花色在数组COLORS的下标值
    public static int getPokeColorSize(String poke) {
        checkPoke(poke);
        String pokeColor = poke.substring(0, 1);
        for (int i = 0; i < COLORS.length; i++) {
            if (pokeColor.equals(COLORS[i])) {
                return i;
            }
        }
        return -1;
    }

    // 得到牌型大小:即每种牌型在types数组中的下标
    public static int getPokTypeSize(String pokeType) {
        if (pokeType == null) {
            throw new NullPointerException("pokeType为空");
        }
        String[] types = {"散牌", "对子", "顺子", "金花", "同花顺", "豹子"};
        for (int i = 0; i < types.length; i++) {
            if (pokeType.equals(types[i])) {
                return i;
            }
        }
        return -1;
    }

    // 判断牌的类型,什么牌都不是就是散牌
    public static POKE_TYPE pokeType(List<String> poke) {
        checkPokeSize(poke);
        if (isPAIR(poke)) {
            return POKE_TYPE.PAIR;
        } else if (isSTRAIGHT_GOLDEN_FLOWER(poke)) {
            return POKE_TYPE.STRAIGHT_GOLDEN_FLOWER;
        } else if (isSTRAIGHT(poke)) {
            return POKE_TYPE.STRAIGHT;
        } else if (isGOLDEN_FLOWER(poke)) {
            return POKE_TYPE.GOLDEN_FLOWER;
        } else if (isBOMB(poke)) {
            return POKE_TYPE.BOMB;
        } else {
            return POKE_TYPE.ZHA_PAI;
        }
    }

    // 是否是金花
    private static boolean isGOLDEN_FLOWER(List<String> poke) {
        String firstPokeColor = getPokeColor(poke.get(0));
        String secondPokeColor = getPokeColor(poke.get(1));
        String lastPokeColor = getPokeColor(poke.get(2));
        return firstPokeColor.equals(secondPokeColor) && secondPokeColor.equals(lastPokeColor);
    }

    // 检验牌的大小是否是三张
    private static void checkPokeSize(List<String> poke) {
        if (poke.size() != 3) {
            throw new IllegalArgumentException("poke的长度必须是3");
        }
    }

    // 是否是顺子
    private static boolean isSTRAIGHT(List<String> poke) {
        // 排序3张牌
        sortPoke(poke);
        String firstPoke = poke.get(0);
        String secondPoke = poke.get(1);
        String lastPoke = poke.get(2);

        int i1 = getPokeNumberSize(firstPoke);
        int i2 = getPokeNumberSize(secondPoke);
        int i3 = getPokeNumberSize(lastPoke);

        firstPoke = getPokeNumber(firstPoke);
        secondPoke = getPokeNumber(secondPoke);
        lastPoke = getPokeNumber(lastPoke);
        if (i2 - 1 == i1 && i2 + 1 == i3) {
            return true;
        } else return firstPoke.equals("2") && secondPoke.equals("3") && lastPoke.equals("A");
    }

    // 理牌
    private static void sortPoke(List<String> poke) {
        checkPokeSize(poke);
        // 比较大小
        poke.sort(FriedGoldenFlower::comparePokeNumber);
    }

    // 比较两张牌的大小
    public static int comparePokeNumber(String poke1, String poke2) {
        // 比较大小
        int size1 = getPokeNumberSize(poke1);
        int size2 = getPokeNumberSize(poke2);
        if (size1 > size2) {
            return size1;
        } else if (size1 == size2) {
            // 大小相等返回0
            return 0;
        } else {
            return size1 - size2;
        }
    }

    // 比较两张牌花色的大小
    public static int comparePokeColor(String poke1, String poke2) {
        int color1 = getPokeColorSize(poke1);
        int color2 = getPokeColorSize(poke2);
        if (color1 > color2) {
            return color1;
        } else {
            return color1 - color2;
        }
    }

    // 得到3张牌中最大的那张
    public static String getMaxPoke(List<String> poke) {
        checkPokeSize(poke);
        sortPoke(poke);
        return poke.get(2);
    }

    // 得到3张牌中最小的那张
    public static String getMinPoke(List<String> poke) {
        checkPokeSize(poke);
        sortPoke(poke);
        return poke.get(0);
    }

    // 得到3张牌中间的那张
    public static String getMidPoke(List<String> poke) {
        checkPokeSize(poke);
        sortPoke(poke);
        return poke.get(1);
    }

    // 比较两个杂牌的大小
    public static int compareZHA_PAI(List<String> poke1, List<String> poke2) {
        String maxPoke1 = getMaxPoke(poke1);
        String maxPoke2 = getMaxPoke(poke2);
        int cmp1 = comparePokeNumber(maxPoke1, maxPoke2);
        if (cmp1 > 0) {
            return 1;
        } else if (cmp1 == 0) {
            String midPoke1 = getMidPoke(poke1);
            String midPoke2 = getMidPoke(poke2);
            int cmp2 = comparePokeNumber(midPoke1, midPoke2);
            if (cmp2 > 0) {
                return 1;
            } else if (cmp2 == 0) {
                String minPoke1 = getMinPoke(poke1);
                String minPoke2 = getMinPoke(poke2);
                int cmp3 = comparePokeNumber(minPoke1, minPoke2);
                if (cmp3 > 0) {
                    return 1;
                } else if (cmp3 == 0) {
                    // 三张牌一样大，比较最大牌的花色
                    return comparePokeColor(maxPoke1, maxPoke2);
                } else {
                    return -1;
                }
            } else {
                return -1;
            }
        } else {
            return -1;
        }
    }

    // 比较两个炸弹大小
    public static int compareBOMB(List<String> poke1, List<String> poke2) {
        String maxPoke1 = getMaxPoke(poke1);
        String maxPoke2 = getMaxPoke(poke2);
        return comparePokeNumber(maxPoke1, maxPoke2);
    }

    // 比较两个对子大小
    public static int comparePAIR(List<String> poke1, List<String> poke2) {
        sortPoke(poke1);
        sortPoke(poke2);
        String pair1 = poke1.get(1);
        String pairOther1 = poke1.get(1).equals(poke1.get(0)) ? poke1.get(2) : poke1.get(0);
        String pair2 = poke2.get(1);
        String pairOther2 = poke2.get(1).equals(poke2.get(0)) ? poke2.get(2) : poke2.get(0);
        int cmp = comparePokeNumber(pair1, pair2);
        if (cmp > 0) {
            return 1;
        } else if (cmp == 0) {
            int cmp2 = comparePokeNumber(pairOther1, pairOther2);
            if (cmp2 > 0) {
                return 1;
            } else if (cmp2 == 0) {
                // 比较对子的花色
                return comparePokeColor(pair1, pair2);
            } else {
                return -1;
            }
        } else {
            return -1;
        }
    }

    // 比较两个顺子大小
    public static int compareSTRAIGHT(List<String> poke1, List<String> poke2) {
        String maxPoke1 = getMaxPoke(poke1);
        String maxPoke2 = getMaxPoke(poke2);
        return comparePokeNumber(maxPoke1, maxPoke2);
    }

    // 比较两个金花大小
    public static int compareGOLDEN_FLOWER(List<String> poke1, List<String> poke2) {
        String maxPoke1 = getMaxPoke(poke1);
        String maxPoke2 = getMaxPoke(poke2);
        int cmp = comparePokeNumber(maxPoke1, maxPoke2);
        if (cmp > 0) {
            return 1;
        } else if (cmp == 0) {
            String midPoke1 = getMidPoke(poke1);
            String midPoke2 = getMidPoke(poke2);
            int cmp2 = comparePokeNumber(midPoke1, midPoke2);
            if (cmp2 > 0) {
                return 1;
            } else if (cmp2 == 0) {
                String minPoke1 = getMinPoke(poke1);
                String minPoke2 = getMinPoke(poke2);
                int cmp3 = comparePokeNumber(minPoke1, minPoke2);
                if (cmp3 > 0) {
                    return 1;
                } else if (cmp3 < 0) {
                    return -1;
                } else {
                    // 三张牌都一样比较最大的花色
                    return comparePokeColor(maxPoke1, maxPoke2);
                }
            } else {
                return -1;
            }
        } else {
            return -1;
        }
    }

    // 比较两个顺金大小
    public static int compareSTRAIGHT_GOLDEN_FLOWER(List<String> poke1, List<String> poke2) {
        String maxPoke1 = getMaxPoke(poke1);
        String maxPoke2 = getMaxPoke(poke2);
        return comparePokeNumber(maxPoke1, maxPoke2);
    }


    // 发牌
    public static void licensing(Player... players) {
        if (players.length > 17) {
            throw new IllegalArgumentException("一副牌最多只能17个人玩");
        }
        System.out.println("==========开始发牌==========");
        for (Player player : players) {
            // 每个人随机发三张牌
            List<String> poke = new ArrayList<>(3);
            for (int i = 0; i < 3; i++) {
                int random = getRandom(POKE.size());
                String num = POKE.remove(random);
                poke.add(num);
            }
            POKE_TYPE poke_type = pokeType(poke);
            player.setPokeType(poke_type.getPokeTypeName());
            player.setPoke(poke);
            System.out.println("玩家:" + player.getName() + "的牌型是===>" + player.getPokeType() + ",牌是===>" + player.getPoke());
        }
        System.out.println("==========发牌完毕==========");
    }

    // 产生随机数,用来随机发牌
    public static int getRandom(int seed) {
        Random random = new Random();
        return random.nextInt(seed);
    }

    // 是否是对子
    private static boolean isPAIR(List<String> poke) {
        checkPokeSize(poke);
        String firstPoke = getPokeNumber(poke.get(0));
        String secondPoke = getPokeNumber(poke.get(1));
        String lastPoke = getPokeNumber(poke.get(2));
        if (isBOMB(poke)) {
            return false;
        }
        return firstPoke.equals(secondPoke) || firstPoke.equals(lastPoke) || lastPoke.equals(secondPoke);
    }

    // 是否是顺金
    private static boolean isSTRAIGHT_GOLDEN_FLOWER(List<String> poke) {
        return isGOLDEN_FLOWER(poke) && isSTRAIGHT(poke);
    }

    // 得到牌的数字
    public static String getPokeNumber(String poke) {
        checkPoke(poke);
        if (poke.length() == 3) {
            return poke.substring(1, 3);
        } else {
            return poke.substring(1, 2);
        }
    }

    // 得到牌的花色
    public static String getPokeColor(String poke) {
        checkPoke(poke);
        return poke.substring(0, 1);
    }

    // 是否是炸弹
    private static boolean isBOMB(List<String> poke) {
        checkPokeSize(poke);
        String firstPoke = getPokeNumber(poke.get(0));
        String secondPoke = getPokeNumber(poke.get(1));
        String lastPoke = getPokeNumber(poke.get(2));
        return firstPoke.equals(secondPoke) && secondPoke.equals(lastPoke);
    }

    // 比较每个玩家牌的大小
    private static void comparePlayerPoke(Player... players) {
        System.out.println("==========开始比较玩家牌的大小==========");
        Arrays.sort(players, (p1, p2) -> {
            String p1PokeType = p1.getPokeType();
            String p2PokeType = p2.getPokeType();
            int i1 = getPokTypeSize(p1PokeType);
            int i2 = getPokTypeSize(p2PokeType);
            if (i1 > i2) {
                return i1;
            } else if (i1 == i2) {
                if (p1PokeType.equals(POKE_TYPE.ZHA_PAI.getPokeTypeName())) {
                    return compareZHA_PAI(p1.poke, p2.poke);
                } else if (p1PokeType.equals(POKE_TYPE.PAIR.getPokeTypeName())) {
                    return comparePAIR(p1.poke, p2.poke);
                } else if (p1PokeType.equals(POKE_TYPE.STRAIGHT.getPokeTypeName())) {
                    return compareSTRAIGHT(p1.poke, p2.poke);
                } else if (p1PokeType.equals(POKE_TYPE.GOLDEN_FLOWER.getPokeTypeName())) {
                    return compareGOLDEN_FLOWER(p1.poke, p2.poke);
                } else if (p1PokeType.equals(POKE_TYPE.STRAIGHT_GOLDEN_FLOWER.getPokeTypeName())) {
                    return compareSTRAIGHT_GOLDEN_FLOWER(p1.poke, p2.poke);
                } else {
                    return compareBOMB(p1.poke, p2.poke);
                }
            } else {
                return i1 - i2;
            }
        });
        System.out.println("==========牌大小比较完毕,顺序如下==========");
        for (int i = players.length-1; i >= 0; i--) {
            System.out.println(players[i].getName() + "的牌:" + players[i].getPoke()+"===>"+players[i].getPokeType());
        }
    }

    enum POKE_TYPE {
        BOMB("豹子"),
        STRAIGHT("顺子"),
        STRAIGHT_GOLDEN_FLOWER("同花顺"),
        PAIR("对子"),
        GOLDEN_FLOWER("金花"),
        ZHA_PAI("散牌");
        private final String pokeTypeName;

        POKE_TYPE(String pokeTypeName) {
            this.pokeTypeName = pokeTypeName;
        }

        public String getPokeTypeName() {
            return pokeTypeName;
        }
    }

    static class Player {
        private String name;
        private String pokeType;
        private List<String> poke;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public String getPokeType() {
            return pokeType;
        }

        public void setPokeType(String pokeType) {
            this.pokeType = pokeType;
        }

        public List<String> getPoke() {
            return poke;
        }

        public void setPoke(List<String> poke) {
            this.poke = poke;
        }
    }
}


